home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
libs
/
knowhow4
/
b&w.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1994-11-12
|
10KB
|
335 lines
#include "b&w.h"
#include "image.h"
#include <string.h>
#include "patterns.h"
inline int bw_pix(int color, int x, int y) // Transform color pix
{ // to B/W using pattern
int sx = x % 8; // We suppose that 1st
int sy = y % 8; // 16 patterns approxi-
return (pattern[color][sy]) & (1 << sx) ? 1 : 0; // mates 16 colors
}
////////////////////////
int pcx_dump(imageP image, uchar* new_image, int nplanes)
{
int x; int count = 1;
int bplin = ((image->xmax + 7) / 8);
x = (nplanes - 1) * bplin; // start of last plane
int shift = 2 * bplin;
int c = 0;
unsigned char ch = image->data[x];
while(1)
{
x++;
if(!(x % bplin)) // end of scan line or end of plane
{
if(x != bplin) // not the end of scan line
x -= shift;
else // end of scan line
{
if(count > 1 || (0xC0 == (0xC0 & ch)))
new_image[c++] = (count | 128 | 64);
new_image[c++] = ch;
break;
}
}
if(ch == image->data[x])
{
if(count == 63)
{
if(count > 1 || (0xC0 == (0xC0 & ch)))
new_image[c++] = (count | 128 | 64);
new_image[c++] = ch; // Write pattern
count = 1;
}
else
count++;
}
else
{
if(count > 1 || (0xC0 == (0xC0 & ch)))
new_image[c++] = (count | 128 | 64);
new_image[c++] = ch; // Write pattern
count = 1;
ch = image->data[x];
}
}
return c;
}
//////////////////////////
void dither_image(imageP image, int y)
{
int xmax = image->xmax + 1;
for(int x = 0; x < xmax; x++)
image_put_pixel(image, loc(x, 0),
(bw_pix((uchar)(
image_get_pixel(image, loc(x, 0), 1, N_PLANES)),
x, y) ? 0 : 1), 1, 1);
}
//////////////////////////
int pcx_col_to_bw(char* src_name, char* dest_name)
{
if(!strcmp(dest_name, src_name))
return 0;
FILE* f = fopen(src_name, "rb");
if(f == NULL)
{
fclose(f);
return 0;
}
FILE* f1 = fopen(dest_name, "wb");
pcxheader p;
pcxstream pcxF(f);
get_pcx_header(&pcxF, &p);
/* The following variable is absolutely unnecessary. But Paintbrush use
16-bit rounded files - I don't know why. Use old_bplin for compatibility.
*/
int old_bplin = p.bplin;
int np = p.nplanes;
put_pcx_header(f1, &p, loc(p.x2 - p.x1 + 1, p.y2 - p.y1 + 1), 1, 1);
p.nplanes = np;
imageP image = (imageP)malloc(old_bplin/*p.bplin*/ * p.nplanes + sizeof(imageType));
char* new_image = new uchar[p.bplin * p.nplanes];
image->xmax = (p.x2 - p.x1 + 1 + 7) / 8 * 8 - 1;
image->ymax = 0;
int x; int y = 0; int count;
int plane;
plane = x = (p.nplanes - 1) * p.bplin; // start of last plane
int height = p.y2 - p.y1 + 1;
int height1;
int shift = 2 * p.bplin;
while(y <= height)
{
unsigned char ch = pcxF.get(); // read char
if((ch & 0xC0 )==0xC0) // if two upper bits == 1
{
count = 63 & ch; // use 6 low bits as counter
ch = pcxF.get();
for(int j = 0; j < count; j++)
{
image->data[x] = ch;
x++;
if(x == old_bplin)//p.bplin)
{
dither_image(image, y);
int len = pcx_dump(image, new_image, 1);
fwrite(new_image, len, 1, f1);
x = plane;
y++;
}
else
if(!(x % old_bplin))//p.bplin))
x -= shift;
}
}
else
{
(unsigned char)(image->data[x]) = ch;
x++;
if(x == old_bplin)//p.bplin)
{
dither_image(image, y);
int len = pcx_dump(image, new_image, 1);
fwrite(new_image, len, 1, f1);
x = plane;
y++;
}
else
if(!(x % old_bplin))//p.bplin))
x -= shift;
}
}
delete image;
delete new_image;
fclose(f);
fclose(f1);
return 1;
}
//////////////////////////
int pcx_bw_to_col(char* src_name, char* dest_name)
{
if(!strcmp(dest_name, src_name))
return 0;
FILE* f = fopen(src_name, "rb");
if(f == NULL)
{
fclose(f);
return 0;
}
pcxheader p;
pcxstream pcxF(f);
get_pcx_header(&pcxF, &p);
/* The following variable is absolutely unnecessary. But Paintbrush use
16-bit rounded files - I don't know why. Use old_bplin for compatibility.
*/
int old_bplin = p.bplin;
if(p.bitpx == 1 && p.nplanes == N_PLANES)
{
fclose(f);
return 0;
}
FILE* f1 = fopen(dest_name, "wb");
int np = p.nplanes;
put_pcx_header(f1, &p, loc(p.x2 - p.x1 + 1, p.y2 - p.y1 + 1), 1, 4);
p.nplanes = np;
imageP image = (imageP)malloc(p.bplin * p.nplanes + sizeof(imageType));
char* new_image = new uchar[p.bplin * p.nplanes];
image->xmax = (p.x2 - p.x1 + 1 + 7) / 8 * 8 - 1;
image->ymax = 0;
int x; int y = 0; int count;
int plane;
plane = x = (p.nplanes - 1) * p.bplin; // start of last plane
int height = p.y2 - p.y1 + 1;
int height1;
int shift = 2 * p.bplin;
while(y <= height)
{
unsigned char ch = pcxF.get(); // read char
if((ch & 0xC0 )==0xC0) // if two upper bits == 1
{
count = 63 & ch; // use 6 low bits as counter
ch = pcxF.get();
for(int j = 0; j < count; j++)
{
image->data[x] = ch;
x++;
if(x == old_bplin)//p.bplin)
{
int len = pcx_dump(image, new_image, 1);
for(int t = 0; t < N_PLANES; t++)
{
fwrite(new_image, len, 1, f1);
}
x = plane;
y++;
}
else
if(!(x % old_bplin))//p.bplin))
x -= shift;
}
}
else
{
(unsigned char)(image->data[x]) = ch;
x++;
if(x == old_bplin)//p.bplin)
{
int len = pcx_dump(image, new_image, 1);
for(int t = 0; t < N_PLANES; t++)
fwrite(new_image, len, 1, f1);
x = plane;
y++;
}
else
if(!(x % old_bplin))//p.bplin))
x -= shift;
}
}
delete image;
delete new_image;
fclose(f);
fclose(f1);
return 1;
}
///////////////////////// Demo code ////////////////////////
/*
#include <iostream.h>
#include "dir.h"
void main( int argc, char *argv[] )
{
char src_name[MAXPATH];
char dest_name[MAXPATH];
if(argc < 3)
{
cout << " ██████████████████████ FREEWARE █████████████████\n";
cout << " ██ ██\n";
cout << " ██ B&W Utility. (C) Stepan S. Vartanov, 1994. ██\n";
cout << " ██ ██\n";
cout << " █████████████████████████████████████████████████\n";
cout << "╔═══════════════════════════════════════════════════════════════╗\n";
cout << "║ Task: Color to B&W PCX files conversion ║\n";
cout << "║ Usage: b&w.exe <src file > <result> <pattern> ║\n";
cout << "║ Example: b&w.exe color.pcx bw.pcx ║\n";
cout << "║ b&w.exe color.pcx bw.pcx 1000111101010101 ║\n";
cout << "║ file masks (*.pcx) does not supported ║\n";
cout << "║ Pattern determines, which of 16 colors should be black (0) ║\n";
cout << "║ and which white (1) ║\n";
cout << "╚═══════════════════════════════════════════════════════════════╝\n";
return;
}
if(argc >= 3)
{
strcpy(src_name, argv[1]);
strcpy(dest_name, argv[2]);
}
if(argc == 4)
{
if(strlen(argv[3]) < 16)
{
cout << "Use 16 colors in mask\n";
return;
}
for(int i = 0; i < 16; i++)
{
if(argv[3][i] == '0')
memset(pattern[i], 255, 8);
else
memset(pattern[i], 0, 8);
}
}
if(!strcmp(dest_name, src_name))
{
pcx_col_to_bw(src_name, "tmp____u.pcy");
unlink(src_name);
rename("tmp____u.pcy", src_name);
}
else
pcx_col_to_bw(src_name, dest_name);
cout << "KNOW-HOW 5.0,Software development kit,Library in source codes (Borland C++ 3.x)\n";
cout << "█████████████████████████████████████████████████████████████████████████████\n";
cout << ">>> KNOW-HOW.Interface: GUI, LJ fonts(SFP) screen output, PCX, multiple over-\n";
cout << "lapped windows, Scripts and macroses. DOS\n";
cout << ">>> KNOW-HOW.DEBUGGER: For any situations, including hang-up. DOS\n";
cout << ">>> KNOW_HOW.GRAPHICS: Using common code for any graphics library. Now it is\n";
cout << "realized now for BGI and Windows GDI. Scrolling, Zooming, reflection of image,\n";
cout << "rotations and complex rotations. Rotated and filled BGI fonts. DOS, WINDOWS\n";
cout << ">>> KNOW-HOW.SLANG: Basic-like language. Multy-file programs, FOR, IF and so\n";
cout << "on operators. User could derive from Slang the child class with new operators\n";
cout << "to access functions of his concrete package. DOS, WINDOWS\n";
cout << ">>> KNOW-HOW.VECTOR: Vector pictures editor. Simple KNOW-HOW.GRAPHICS\n";
cout << "interpreter in DOS or Windows. Powerfull tool for maketing BGI, GDI and so on.\n";
cout << ">>> KNOW-HOW.DRAW: PCX pictures editor. All standart image-editing functions.\n";
cout << ">>> KNOW-HOW.PRINT: Create on disk virtual screen of any size, show, scroll\n";
cout << "on screen or print on different printers with any deformation. DOS.\n";
cout << ">>> KNOW-HOW.DATASHELL: Shell for Paradox Engine 3.01 or any other database\n";
cout << "engine. View and edit tables and querries in Paradox-like style. Multy-table\n";
cout << "QBE querries. Print reports in user-defined form. DOS.\n";
cout << ">>> KNOW-HOW.GRAF: Business and scientific diagrams. Line, Markers,\n";
cout << "Line-and-markers, Bar, 3d-Bar, Stacked bar graphs... DOS, WINDOWS\n";
}
*/